package pieces;

import java.util.ArrayList;
import model.*;

/**
 * This class is the broadest interpretation of a Piece in Chess. See each subclass for more detail.
 * @author Sacha Best
 */
public abstract class Piece
{
	/**
	 * Theses constants represent the IDs of each type of piece.
	 */
	public static final int PAWN = 5, BISHOP = 6, KNIGHT = 7, ROOK = 8, QUEEN = 9, KING = 10;
	/**
	 * These constants represnt the values of each piece.
	 */
	public static final int PAWN_VALUE = 1, BISHOP_VALUE = 3, KNIGHT_EARLY_VALUE = 6;
	/**
	 * These constants represnt the values of each piece.
	 */
	public static final int KNIGHT_VALUE = 3, ROOK_VALUE = 5, QUEEN_VALUE = 9;
	
	/**
	 * This {@link model.Location} is where the Piece resides.
	 */
	protected Location currentLoc;
	/**
	 * This {@link model.GridGame<E>} is the grid the piece is on.
	 */
	protected final GridGame<Piece> grid;
	/**
	 * This int holds the color of the piece.
	 * @see {@link players.Player}
	 */
	protected final int color;
	/**
	 * This field holds one of the above constant values for the ID of a piece
	 */
	public final int ID;

	/**
	 * Creates a new piece at the given {@link model.Location}, in the given {@link model.GridGame<E>}, with the
	 * given ID, and finally, with the given color.
	 * @param currentLoc - This {@link model.Location} is where the Piece resides.
	 * @param grid - This {@link model.GridGame<E>} is the grid the piece is on.
	 * @param id - This field holds one of the above constant values for the ID of a piece
	 * @param color - This int holds the color of the piece
	 */
	public Piece(Location currentLoc, GridGame<Piece> grid, int id, int color)
	{
		this.currentLoc = currentLoc;
		this.grid = grid;
		this.ID = id;
		this.color = color;
	}
	/**
	 * @param direction - the direction in which to look
	 * @return the {@link model.Location} in the given direction
	 */
	public Location getLocationInDirection(int direction)
	{
		Location returned = currentLoc.getAdjacentLocation(direction);
		if (!grid.inBounds(returned))
			returned = null;
		return returned;
	}
	/**
	 * @return the {@link model.Location} of the piece
	 */
	public Location getLocation()
	{
		return currentLoc;
	}
	/**
	 * @param newLoc - the new {@link model.Location} of the piece
	 */
	public void setLocation(Location newLoc)
	{
		currentLoc = newLoc;
	}
	/**
	 * @return the Piece's color
	 */
	public final int getColor()
	{
		return color;
	}
	/**
	 * @return the Piece's ID
	 */
	public int getID() 
	{
		return ID;
	}
	@Override
	/**
	 * Determines whether or not two Pieces are equal. NOTE: using "==" will determine whether the are the EXACT same
	 * Piece, as two different Pieces can have the same properties.
	 * @return true if the two Pieces are equal, false otherise
	 */
	public boolean equals(Object other)
	{
		if (!(other instanceof Piece))
			return false;
		else
		{
			Piece compare = (Piece) other;
			return getLocation().getRow() == compare.getLocation().getRow() && getLocation().getCol() == compare.getLocation().getCol();
		}
	}
	/**
	 * @return the move locations for a given piece (depends on the type of Piece).
	 */
	public abstract ArrayList<Location> getMoveLocations();
	public abstract int getValue();
}
